package com.jiuxian.scheduling.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by wangjingqing on 2017/11/15.
 */
public class SiteUtil {

    public static String FORMAT_SECOND = "yyyy-MM-dd HH:mm:ss";

    public static String getRequestIp(HttpServletRequest request) {
        String ip = request.getHeader("HttpClient-Proxy-For");
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("http_x_forwarded_for"); // cdn
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Forwarded-For");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip != null && ip.trim().length() > 0) {
            if (ip.indexOf(",") > 0) {
                String ips[] = ip.split(",");
                return ips[ips.length - 1];
            } else {
                return ip;
            }
        } else {
            return "0.0.0.0";
        }
    }


    /**
     * 获取指定的方法<br>
     * @param obj
     * @param methodName
     * @param paras
     * @return
     */
    public static Method getMethod(Object obj,String methodName,String[] paras){
        Method[] methods = obj.getClass().getMethods();
        Method method = null;
        for(Method info : methods){
            if(info.getName().equals(methodName) && info.getParameterCount() == paras.length){
                method = info;
                break;
            }
        }
        return method;
    }

    /**
     * 根据类型和值转换对象数组<br>
     * @param tClass 类型
     * @param parameter 参数
     * @return Object[]
     */
    public static Object[] getMethodParameter(Class<?>[] tClass,String[] parameter){
        Object[] objects = new Object[tClass.length];

        for(int i = 0; i < tClass.length;i++){
            objects[i] = convertBaseType(tClass[i],parameter[i]);
        }
        return objects;
    }
    /**
     * 获取前几秒时间<br>
     * @param date 指定时间
     * @param second 提前的秒数
     * @return Date
     */
    public static Date getDate(Date date,int second){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.SECOND, second);
        return c.getTime();
    }

    /**
     * 根据类型获取指定值<br>
     * @param type 类型
     * @param value 值
     * @return Object
     */
    public static <T> T convertBaseType(Class<T> type,String value){
        if(type.equals(Integer.class) || type.equals(int.class)){
            return (T)Integer.valueOf(value);
        }else if(type.equals(Character.class) || type.equals(char.class)){
            return (T)Character.valueOf(value.charAt(0));
        }else if(type.equals(Byte.class) || type.equals(byte.class)){
            return (T)Byte.valueOf(value);
        }else if(type.equals(Short.class) || type.equals(short.class)){
            return (T)Short.valueOf(value);
        }else if(type.equals(Long.class) || type.equals(long.class)){
            return (T)Long.valueOf(value);
        }else if(type.equals(Float.class) || type.equals(float.class)){
            return (T)Float.valueOf(value);
        }else if(type.equals(Double.class) || type.equals(double.class)){
            return (T)Double.valueOf(value);
        }else if(type.equals(String.class)){
            return (T)value;
        }else if(type.equals(BigDecimal.class)){
            return (T)new BigDecimal(value);
        }else if(type.equals(Date.class)){
            return (T)convertStr(value,FORMAT_SECOND);
        }
        return null;
    }

    /**
     * 字符串转时间<br>
     * @param date 时间字符串<br>
     * @param format 格式
     * @return Date
     */
    public static Date convertStr(String date,String format){
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat(format);
            return dateFormat.parse(date);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 时间转字符串<br>
     * @param date 时间<br>
     * @param format 格式
     * @return String
     */
    public static String convertDate(Date date,String format){
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat(format);
            return dateFormat.format(date);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取异常信息<br>
     * @param message Exception
     * @param trace StackTraceElement
     * @return String
     */
    public static String getExceptionAllInfo(String message,StackTraceElement[] trace){
        StringBuffer sOut = new StringBuffer();
        if(StringUtils.isNotBlank(message)){
            sOut.append(message);
        }
        sOut.append("\r\n");
        for (StackTraceElement s : trace) {
            sOut.append("\tat ").append(s).append("\r\n");
        }
        return sOut.toString();
    }

    /**
     *
     * @param paras
     * @return
     */
    public static String[] getStringForJSON(String paras){
        if(StringUtils.isBlank(paras)){
            return new String[]{};
        }
        JSONObject obj = JSONObject.parseObject(paras);
        Collection<Object> values = obj.values();
        if(CollectionUtils.isNotEmpty(values)){
            String[] reDate = new String[values.size()];
            Iterator<Object> iterator = values.iterator();
            int index = 0;
            while(iterator.hasNext()){
                reDate[index] = iterator.next().toString();
                index++;
            }
            return reDate;
        }
        return new String[]{};
    }

    /**
     * json字符串转换Map<String,String>
     * @param paras String
     * @return Map<String,String>
     */
    public static Map<String,String> getMapForJSON(String paras){
        Map<String,String> reDate = new HashMap<>();
        if(StringUtils.isBlank(paras)){
            return reDate;
        }
        JSONObject obj = JSONObject.parseObject(paras);
        Collection<String> keys = obj.keySet();
        keys.forEach((key)->reDate.put(key,obj.get(key).toString()));
        return reDate;
    }
}
